package com.xiyu.service.repository.devops.customer;

import com.xiyu.service.model.devops.customer.DevopsCustomerFetcher;
import com.xiyu.service.model.devops.project.DevopsProjectFetcher;
import com.xiyu.service.model.devops.project.DevopsProjectVersionFetcher;
import com.xiyu.service.model.devops.server.DevopsServerFetcher;
import com.xiyu.service.vo.infra.devops.customer.CustomerGetServerCustomerInfoInput;
import com.xiyu.service.vo.infra.devops.customer.CustomerPageQueryInput;
import com.xiyu.service.model.devops.customer.DevopsCustomer;
import com.xiyu.service.model.devops.customer.DevopsCustomerTable;
import org.babyfish.jimmer.spring.repository.JRepository;
import org.babyfish.jimmer.Page;
import org.babyfish.jimmer.sql.ast.Predicate;
import org.springframework.util.StringUtils;
import java.util.Optional;
import java.util.List;

public interface DevopsCustomerRepository extends JRepository<DevopsCustomer, Long> {
    DevopsCustomerTable devopsCustomerTable = DevopsCustomerTable.$;

    default Page<DevopsCustomer> pageQuery(CustomerPageQueryInput inputVO){
        return sql().createQuery(devopsCustomerTable)
                .whereIf(StringUtils.hasText(inputVO.getCustomerName()), () -> devopsCustomerTable.customerName().like(inputVO.getCustomerName()))
                .whereIf(StringUtils.hasText(inputVO.getCustomerNo()), () -> devopsCustomerTable.customerNo().like(inputVO.getCustomerNo()))
                .whereIf(StringUtils.hasText(inputVO.getProjectName()), () -> devopsCustomerTable.version().project().name().like(inputVO.getProjectName()))
                .whereIf(StringUtils.hasText(inputVO.getVersion()), () -> devopsCustomerTable.version().version().like(inputVO.getVersion()))
                .whereIf(StringUtils.hasText(inputVO.getDatabaseName()), () -> devopsCustomerTable.databaseName().like(inputVO.getDatabaseName()))
                .whereIf(StringUtils.hasText(inputVO.getServerIp()), () -> devopsCustomerTable.server().ip().like(inputVO.getServerIp()))
                .orderBy(devopsCustomerTable.id().desc())
                .select(devopsCustomerTable.fetch(DevopsCustomerFetcher.$.allTableFields()
                        .version(DevopsProjectVersionFetcher.$.allTableFields().project(DevopsProjectFetcher.$.allTableFields()))
                        .server(DevopsServerFetcher.$.allTableFields())))
                .fetchPage(inputVO.getPageNo() - 1, inputVO.getPageSize());
    }

    default Optional<DevopsCustomer> singleGet(Long id){
        return sql().createQuery(devopsCustomerTable)
                .where(devopsCustomerTable.id().eq(id))
                .select(devopsCustomerTable.fetch(DevopsCustomerFetcher.$.allTableFields()
                        .version(DevopsProjectVersionFetcher.$.allTableFields())
                ))
                .fetchOptional();
    }

    default List<DevopsCustomer> getByIpAndProject(CustomerGetServerCustomerInfoInput inputVO, String ip){
        return sql().createQuery(devopsCustomerTable)
                .where(devopsCustomerTable.server().ip().eq(ip))
                .where(devopsCustomerTable.version().project().projectNo().eq(inputVO.getProjectNo()))
                .select(devopsCustomerTable.fetch(DevopsCustomerFetcher.$.allTableFields()
                        .server(DevopsServerFetcher.$.allTableFields())
                        .version(DevopsProjectVersionFetcher.$.allTableFields().project(DevopsProjectFetcher.$.allTableFields()))
                ))
                .execute();
    }

    default Optional<DevopsCustomer> findByCustomerNameAndProjectNo(String customerName, String projectNo){
        return sql().createQuery(devopsCustomerTable)
                .where(devopsCustomerTable.customerNo().eq(customerName))
                .where(devopsCustomerTable.version().project().projectNo().eqIf(projectNo))
                .select(devopsCustomerTable.fetch(DevopsCustomerFetcher.$.allTableFields()
                        .server(DevopsServerFetcher.$.allTableFields())
                        .version(DevopsProjectVersionFetcher.$.allTableFields().project(DevopsProjectFetcher.$.allTableFields()))
                )).fetchOptional();
    }

    default Optional<DevopsCustomer> findByUrlAndProjectNo(String url, String projectNo){
        return sql().createQuery(devopsCustomerTable)
                .where(Predicate.or(
                        devopsCustomerTable.server().ip().eq(url),
                        devopsCustomerTable.server().domainName().eq(url),
                        devopsCustomerTable.server().internalIp().eq(url)
                ))
                .where(devopsCustomerTable.version().project().projectNo().eqIf(projectNo))
                .select(devopsCustomerTable.fetch(DevopsCustomerFetcher.$.allTableFields()
                        .server(DevopsServerFetcher.$.allTableFields())
                        .version(DevopsProjectVersionFetcher.$.allTableFields().project(DevopsProjectFetcher.$.allTableFields()))
                )).fetchOptional();
    }

    default Optional<DevopsCustomer> findDetailById(Long id){
        return sql().createQuery(devopsCustomerTable)
                .where(devopsCustomerTable.id().eq(id))
                .select(devopsCustomerTable.fetch(DevopsCustomerFetcher.$.allTableFields()
                        .server(DevopsServerFetcher.$.allTableFields())
                        .version(DevopsProjectVersionFetcher.$.allTableFields().project(DevopsProjectFetcher.$.allTableFields()))
                )).fetchOptional();
    }

    default void updateVersion(Long customerId, Long versionId){
        sql().createUpdate(devopsCustomerTable)
                .where(devopsCustomerTable.id().eq(customerId))
                .set(devopsCustomerTable.versionId(), versionId)
                .execute();
    }

    Optional<DevopsCustomer> findByCustomerNo(String customerNo);


}